package wiki

import (
	"database/sql"
	"gitee.com/hardykay/mysql_wiki/conn"
	"strings"
)

func NewTable(name string) *Table {
	t := &Table{
		Schema: conn.Config.MySQL.Database,
		Name:   name,
	}
	t.init()
	return t
}

type Table struct {
	Schema  string // 数据库名
	Name    string // 表名
	Comment string // 备注
	Error   error
	Columns []Column
}
type Column struct {
	Name     string         //字段名
	Type     string         // 字段类型
	NullAble string         // 是否为空
	Comment  string         // 备注
	Default  sql.NullString // 默认值
}

var columnMsg = Column{
	Name:     "列名",
	Type:     "数据类型",
	NullAble: "可空",
	Comment:  "意义",
	Default:  sql.NullString{String: "默认值", Valid: true},
}

var columnApart = Column{
	Name:     "-",
	Type:     "-",
	NullAble: "-",
	Comment:  "-",
	Default:  sql.NullString{String: "-", Valid: true},
}

const (
	Separator = "|"
	Section   = "##"
	Space     = " "
)

func (t *Table) init() {
	// 获取表信息
	t.getTableComment()
	t.getColumns()
}

// 获取表备注
func (t *Table) getTableComment() {
	row := conn.DB.QueryRow("SELECT TABLE_COMMENT FROM TABLES WHERE TABLE_SCHEMA=? AND TABLE_NAME =?", t.Schema, t.Name)
	if err := row.Scan(&t.Comment); err != nil {
		t.Error = err
		return
	}
}

// 获取表字段
func (t *Table) getColumns() {
	rows, err := conn.DB.Query("SELECT COLUMN_NAME,COLUMN_TYPE,IS_NULLABLE,COLUMN_COMMENT,COLUMN_DEFAULT FROM COLUMNS WHERE TABLE_SCHEMA=? AND TABLE_NAME=?", t.Schema, t.Name)
	defer func() {
		if rows != nil {
			rows.Close()
		}
	}()
	if err != nil {
		t.Error = err
		return
	}
	var column Column
	for rows.Next() {
		err = rows.Scan(&column.Name, &column.Type, &column.NullAble, &column.Comment, &column.Default)
		if err != nil {
			t.Error = err
			return
		}
		if column.Name == "id" && column.Comment == "" {
			column.Comment = "主键"
		}
		t.Columns = append(t.Columns, column)
	}
}

func (t Table) String() string {
	return t.GetWiki()
}

func (t Table) GetWiki() (s string) {
	arr := make([]string, 0, len(t.Columns)+3)
	arr = append(arr, connectString(Section, Space, t.Name, Space, t.Comment))
	arr = append(arr, columnMsg.String())
	arr = append(arr, columnApart.String())
	for _, v := range t.Columns {
		arr = append(arr, v.String())
	}
	return lineBreak(arr)
}

func (c Column) String() string {
	return Separator + strings.Join([]string{c.Name, c.NullAbleString(), c.Comment, c.Type, c.Default.String}, Separator) + Separator
}
func (c Column) NullAbleString() string {
	if c.NullAble == "YES" {
		return "是"
	} else if c.NullAble == "NO" {
		return "否"
	}
	return c.NullAble
}
func connectString(s ...string) string {
	return strings.Join(s, "")
}
func lineBreak(s []string) string {
	return strings.Join(s, "\n\r")
}
